#ifndef quantlib_amccalibrationion_i 
#define quantlib_amccalibrationion_i 

%include date.i 

%{ 
using QuantLib::AMCCashflows; 
using QuantLib::Observables; 
using QuantLib::PayoffsBase; 
using QuantLib::PayoffFactory; 
typedef boost::shared_ptr<Observables> ObservablesPtr; 
typedef boost::shared_ptr<AMCCashflows> AMCCashflowsPtr; 
typedef boost::shared_ptr<PayoffsBase> PayoffsBasePtr; 
typedef boost::shared_ptr<PayoffFactory> PayoffFactoryPtr; 
%} 

%rename(Observables) ObservablesPtr; 
class ObservablesPtr { 
        public: 
                %extend { 
                        ObservablesPtr(std::vector<Date> timeIndices) { 
                                return new ObservablesPtr(new Observables(timeIndices)); 
                        } 
                        
                        int PushObservable(std::string id, std::vector<double> timeSeries) { 
                                return (*self)->PushObservable(id, timeSeries); 
                        } 
                        
                        double GetObservableAtTime(std::string id, Date timeIndex) const { 
                                return (*self)->GetObservableAtTime(id, timeIndex); 
                        } 
                } 
}; 

%rename(AMCCashflows) AMCCashflowsPtr; 
class AMCCashflowsPtr { 
        public: 
                %extend { 
                        AMCCashflowsPtr() { 
                                return new AMCCashflowsPtr(new AMCCashflows()); 
                        } 
                        
                        int PushCashflow(Date d, PayoffsBasePtr f) { 
                                return (*self)->PushCashflow(d, f); 
                        } 
                        
                        double GetCashflow(Date d, ObservablesPtr o) const { 
                                return (*self)->GetCashflow(d, *o); 
                        } 
                } 
}; 


// %rename(PayoffsBase) PayoffsBasePtr; 
// class PayoffsBasePtr { 
        // public: 
                // %extend { 
                        // PayoffsBasePtr() { 
                                // return new PayoffsBasePtr(new PayoffsBase()); 
                        // } 
                        // virtual double operator()(Observables o) { 
                                // return (*self)->operator(); 
                        // } 
                        
                        // virtual void setDouble(string &s, double d) { 
                                // (*self)->setDouble(s, d); 
                        // } 
                        
                        // virtual void setString(string &s, string d) { 
                                // (*self)->setString(s, d); 
                        // } 
                        
                        // virtual void setDate(string &s, Date d) { 
                                // (*self)->setDate(s, d); 
                        // } 
                // } 
// }; 

%rename(PayoffFactory) PayoffFactoryPtr; 
class PayoffFactory { 
		private:
			PayoffFactory();
        public: 
			static PayoffFactory& instance();
			%extend { 
				 // PayoffFactoryPtr() { 
					// PayoffFactory* p;
					// *p = PayoffFactory::Instance();
					// return new PayoffFactoryPtr(p);
						 // return new PayoffFactoryPtr(*PayoffFactory::Instance()); 
				 // } 
				// PayoffFactory& Instance() {
					// return PayoffFactory::Instance();
				// }
				
				PayoffsBasePtr CreatePayoff(std::string s) {
					return (*self).CreatePayoff(s);
				}
				
				void setDouble(PayoffsBasePtr p, std::string s, double d) {
					p->setDouble(s, d);
				}
				
				void setString(PayoffsBasePtr p, std::string s, std::string d) {
					p->setString(s, d);
				}
				
				void setDate(PayoffsBasePtr p, std::string s, Date d) {
					p->setDate(s, d);
				}				
				
			} 
		
}; 

#endif